/**
 * @param {string[]} tokens
 * @return {number}
 */
// 给你一个字符串数组 tokens ，表示一个根据 逆波兰表示法 表示的算术表达式。

// 请你计算该表达式。返回一个表示表达式值的整数。

// 注意：

// 有效的算符为 '+'、'-'、'*' 和 '/' 。
// 每个操作数（运算对象）都可以是一个整数或者另一个表达式。
// 两个整数之间的除法总是 向零截断 。
// 表达式中不含除零运算。
// 输入是一个根据逆波兰表示法表示的算术表达式。
// 答案及所有中间计算结果可以用 32 位 整数表示。

// 以下是一个使用逆波兰表示法表示的算术表达式的例子：

// 中缀表达式：2 + 3 * 4
// 逆波兰表示法：2 3 4 * +

// 在逆波兰表示法中：

// 每个数字和运算符都用空格分隔开。
// 当遇到一个数字时，将它放入栈中。
// 当遇到一个运算符时，从栈中弹出两个数字进行计算，并将结果再次放入栈中。
// 继续按照上述规则处理剩余的数字和运算符，直到最终得到结果。
// 对于上述示例，可以按照以下步骤进行计算：

// 遇到数字2，将其放入栈中：2
// 遇到数字3，将其放入栈中：2 3
// 遇到数字4，将其放入栈中：2 3 4
// 遇到运算符*，从栈中弹出4和3进行计算，并将结果12放入栈中：2 12
// 遇到运算符+，从栈中弹出12和2进行计算，并将结果14放入栈中。
// 最终结果为14。
// 因此，逆波兰表示法 "2 3 4 * +" 等价于中缀表示法 "2 + 3 * 4"，并且它们的计算结果都为14。

// 逆波兰表示法在计算机科学和计算器设计中有一定的应用，它可以简化表达式的解析和计算过程。

// 示例 1：

// 输入：tokens = ["2","1","+","3","*"]
// 输出：9
// 解释：该算式转化为常见的中缀算术表达式为：((2 + 1) * 3) = 9
// 示例 2：

// 输入：tokens = ["4","13","5","/","+"]
// 输出：6
// 解释：该算式转化为常见的中缀算术表达式为：(4 + (13 / 5)) = 6
// 示例 3：

// 输入：tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
// 输出：22
// 解释：该算式转化为常见的中缀算术表达式为：
//   ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
// = ((10 * (6 / (12 * -11))) + 17) + 5
// = ((10 * (6 / -132)) + 17) + 5
// = ((10 * 0) + 17) + 5
// = (0 + 17) + 5
// = 17 + 5
// = 22
/**
 * 何谓逆波兰表示法
 *  每个数字和运算符都用空格隔开 当遇到一个运算符时, 从栈中弹出两个数字进行计算 并将结果放入栈中
 */
var evalRPN = function (tokens) {
  const len = tokens.length
  const stack = new Array(Math.floor((len + 1) / 2)).fill(0)
  let index = -1
  for (let i = 0; i < len; i++) {
    const token = tokens[i]
    if (token === '+') {
      // index 1 index-- 0
      // stack[0] = stack[0] + stack[1] = 3 stack= [3]
      index--
      stack[index] += stack[index + 1]
    } else if (token === '-') {
      index--
      stack[index] -= stack[index + 1]
    } else if (token === '*') {
      // 1 index-- 0 stack[3,3]
      // stack[0] = stack[0] * stack[1]
      index--
      stack[index] *= stack[index + 1]
    } else if (token === '/') {
      // index-- 1 stack[4,13,5]
      // stack[1] = stack[1] / stack[2] ( 13 / 5)  stack[1] = [2] stack[4 ,2, 5]
      index--
      stack[index] = stack[index] / stack[index + 1] > 0 ? Math.floor(stack[index] / stack[index + 1]) : Math.ceil(stack[index] / stack[index + 1]);
    } else {
    // case: 1
      //  2 index++ 0
      // stack[0]= 2 stack[2]
      // 1 index++ 1
      // stack[1] = 1 stack[2, 1]
      // 3 index++ 1 stack[1] = 3 stack[3,3]
    // case: 2
      // 4 index++ 0 stack[4]
      //13 index++ 1 stack[4, 13]
      // 5 index++ 2 stack[4, 13, 5]
      index++
      stack[index] = parseInt(token)
    }
    console.log(stack);
  }
  return stack[index]
};
const tokens = ["2", "1", "+", "3", "*"]
console.log(evalRPN(tokens));
console.log(evalRPN(["4", "13", "5", "/", "+"]));
// var evalRPN = function(tokens) {
//   const stack = [];
//   const n = tokens.length;
//   for (let i = 0; i < n; i++) {
//       const token = tokens[i];
//       if (isNumber(token)) {
//           stack.push(parseInt(token));
//       } else {
//           const num2 = stack.pop();
//           const num1 = stack.pop();
//           if (token === '+') {
//               stack.push(num1 + num2);
//           } else if (token === '-') {
//               stack.push(num1 - num2);
//           } else if (token === '*') {
//               stack.push(num1 * num2);
//           } else if (token === '/') {
//               stack.push(num1 / num2 > 0 ? Math.floor(num1 / num2) : Math.ceil(num1 / num2));
//           }
//       }
//   }
//   return stack.pop();
// };

// const isNumber = (token) => {
//   return !('+' === token || '-' === token || '*' === token || '/' === token );
// }
